package ch.sv7.tool.dbmanager.db.fixbuilder;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import ch.sv7.tool.dbmanager.Context;
import ch.sv7.tool.dbmanager.db.ForeignKeySchema;
import ch.sv7.tool.dbmanager.db.TableSchema;
import ch.sv7.tool.dbmanager.db.dialect.Dialect;
import ch.sv7.tool.dbmanager.db.difference.AbstractTableDifference;
import ch.sv7.tool.dbmanager.db.difference.SchemaDifference;
import ch.sv7.tool.dbmanager.db.fix.CreateForeignKeyFix;
import ch.sv7.tool.dbmanager.db.fix.CreateTableFix;
import ch.sv7.tool.dbmanager.db.fix.DropForeignKeyFix;
import ch.sv7.tool.dbmanager.db.fix.DropTableFix;
import ch.sv7.tool.dbmanager.db.fix.SchemaFix;

/**
 * TODO: Document me!
 *
 * @author svt
 *
 */
public class EmptyTableFixBuilder implements FilterFixBuilder {

	private Set foreignKeys = new HashSet();
	
	public SchemaFix[] createFixes(SchemaDifference difference, Dialect dialect, Context context) {
		AbstractTableDifference tableDifference = (AbstractTableDifference)difference;
		TableSchema actualTableSchema = tableDifference.getActualTableSchema();
		TableSchema expectedTableSchema = tableDifference.getExpectedTableSchema();
		if (!actualTableSchema.isTableEmpty()) {
			throw new RuntimeException("This table should be empty to be managed by this " + this.getClass().getName());
		}
		List fixes = new ArrayList();
		// Create a GroupedSchemaFix to ensure that table drop executed first
		/*
		GroupedSchemaFix groupedFix = 
			new GroupedSchemaFix(
					expectedTableSchema, 
					SchemaFix.ACTION_EDIT, 
					SchemaFix.PRIORITY_TABLE_DROP, 
					"Drop empty table " + actualTableSchema.getName());
		fixes.add(groupedFix);
		*/
		
		// We drop first every referenced fk
		List actualFK = actualTableSchema.getReferencedForeignKeys();
		for (int i=0; i<actualFK.size(); i++) {
			ForeignKeySchema fk = (ForeignKeySchema)actualFK.get(i);
			SchemaFix fix = new DropForeignKeyFix(fk);
			fixes.add(fix);
			//groupedFix.addFix(fix);
		}
		
		// We drop the table
		fixes.add(new DropTableFix(actualTableSchema));
		//groupedFix.addFix(new DropTableFix(actualTableSchema));
		
		// We recreate the table then
		fixes.add(new CreateTableFix(expectedTableSchema));
		
		// We create then every needed foreign key
		// This is not done in grouped since other object
		// might be needed
		List expectedFK = expectedTableSchema.getReferencedForeignKeys();
		for (int i=0; i< expectedFK.size(); i++) {
			ForeignKeySchema fk = (ForeignKeySchema)expectedFK.get(i);
			SchemaFix fix = new CreateForeignKeyFix(fk);
			fixes.add(fix);
			foreignKeys.add(fix.getActionTarget().getSchemaIdentifier());
		}
		
		return (SchemaFix[])fixes.toArray(new SchemaFix[fixes.size()]);					
	}

	public boolean ignoreFix(SchemaFix fix) {
		String identifier = fix.getActionTarget().getSchemaIdentifier();
		/*
		 * Remove all editions on foreign keys that will be dropped
		 */
		if (foreignKeys.contains(identifier) && fix.getAction() == SchemaFix.ACTION_EDIT){
			return true;
		}	
		
		return false;
	}

}
